package com.rzjm.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rzjm.api.config.RequestDataHelper;
import com.rzjm.api.dao.DeviceRangeRecordDao;
import com.rzjm.api.dao.DeviceRangeResultDao;
import com.rzjm.api.entity.*;
import com.rzjm.api.entity.dto.Cone;
import com.rzjm.api.entity.dto.Cylinder;
import com.rzjm.api.entity.dto.Rect;
import com.rzjm.api.exception.TransactionalException;
import com.rzjm.api.service.*;
import com.rzjm.api.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class DeviceRangeRecordServiceImpl extends BaseServiceImpl<DeviceRangeRecordDao, DeviceRangeRecord> implements DeviceRangeRecordService {

    @Resource
    private DeviceRangeRecordDao deviceRangeRecordDao;
    @Resource
    private DeviceRangeService deviceRangeService;
    @Resource
    private DeviceRangeResultDao deviceRangeResultDao;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private UserMpService userMpService;
    @Resource
    private UserService userService;
    @Resource
    private ShopService shopService;
    @Resource
    private ParameterService parameterService;


    @Value("${web.appid_mp}")
    private String appidMp;//公众号appid
    @Value("${web.secret_mp}")
    private String secretMp;//公众号secret

    @Override
    @Transactional
    public int addSingleRecord(String deviceNum, String[] dataArray,  String data, String orderNum) {
        int ret = 0;
        try{
            Integer x = Integer.parseInt(dataArray[1],16);
            System.out.println("获取全角度距离值：" + data);
            System.out.println("获取全角度距离值： 十进制： " + x);
            String dataCode = "";
            DeviceRange deviceRange = deviceRangeService.getDeviceInfoByNum(deviceNum);
            if(deviceRange != null){
                dataCode = deviceRange.getDataCode();
                DeviceRangeRecord record = new DeviceRangeRecord();
                record.setDeviceId(deviceRange.getId());
                record.setDataCode(dataCode);
                record.setDeviceNum(deviceNum);
                record.setCreateTime(new Date());
                record.setOrderNum(orderNum);
                //当前角度
                record.setNowAngle(x);
                //斜边长度
                record.setNowBevel(Double.parseDouble(x+""));
                //计算出来的高度
                double height = MathUtil.getVerticalLength(Double.parseDouble(dataArray[0]),Double.parseDouble(x+""));
                record.setNowHeight(height);
                record.setReqDataStr(data);
                ret = deviceRangeRecordDao.insert(record);
                if(ret <= 0){
                    throw new TransactionalException("deviceRangeRecordDao insert error");
                }

                //判断当前这批数据上来的够不够90
                long recordCount = getRecordCount(deviceNum,dataCode);
                if(recordCount >= 90){
                    System.out.println("数据数：" + recordCount);
                    // 寻找最长距离的那一个  点
                    DeviceRangeRecord maxLength = getMaxBevelByDeviceId(deviceNum,dataCode);
                    if(maxLength != null) {
                        //根据最长距离的点，来计算 空余 整体体积
                        deviceRange = getLastEmptyVolume(maxLength,deviceRange,dataCode);
                        ret = deviceRangeService.resetDevice(deviceRange);
                        if(ret <= 0){
                            throw new TransactionalException("deviceRangeService updateById error");
                        }else{
                            System.out.println("数据保存成功：");
                        }
                    }else{
                        System.out.println("未取到当前编码的数据：" + dataCode);
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("addSingleRecord system error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int addSingleRecordOil(String deviceNum, String data, String orderNum) {
        int ret = 0;
        try{
            System.out.println("获取全角度距离值：" + data);
            String dataCode = "";


            //判断当前是否需要重置 记录表
            String tableName = addNowMonthRecordTable();

            DeviceRange deviceRange = deviceRangeService.getDeviceInfoByNum(deviceNum);
            if(deviceRange != null){
                dataCode = deviceRange.getDataCode();
                DeviceRangeRecord record = new DeviceRangeRecord();

                Map<String,Object> map = new HashMap<>();
                map.put("ck_device_range_record", tableName);
                RequestDataHelper.setRequestData(map);

                record.setDeviceId(deviceRange.getId());
                record.setDataCode(dataCode);
                record.setDeviceNum(deviceNum);
                record.setCreateTime(new Date());
                record.setOrderNum(orderNum);
                //当前角度
                record.setNowAngle(90);
                //斜边长度

                //测量值
                double height = Double.parseDouble(data) / 1000;
                System.out.println("当前油罐测量值： 十进制： " + height);
                double oilHeight = 0d;
                if(deviceRange.getErrorHeight()!= null){
                    height = (Double.parseDouble(data) + deviceRange.getErrorHeight()) / 1000;
                    oilHeight = MathUtil.getDoubleUpThree(height);
                }else{
                    oilHeight = MathUtil.getDoubleUpThree(height);
                }
                record.setNowBevel(oilHeight);
                //测量值是剩余空间距离，需要用 最大量程减去测量值  得到 最终的高度
                record.setNowHeight(oilHeight);
                record.setReqDataStr(data);
                ret = deviceRangeRecordDao.insert(record);
                if(ret <= 0){
                    throw new TransactionalException("deviceRangeRecordDao insert error");
                }

                //根据最长距离的点，来计算 空余 整体体积
                deviceRange = getLastEmptyVolumeOil(oilHeight,deviceRange);
                if(deviceRange.getIsEmpty() == 1){
                    deviceRange.setStoreState(0);
                }
                ret = deviceRangeService.resetDevice(deviceRange);
                if(ret <= 0){
                    throw new TransactionalException("deviceRangeService updateById error");
                }else{
                    System.out.println("数据保存成功：");
                }

                DeviceRangeResult rangeResult = new DeviceRangeResult();
                rangeResult.setRecordTableName(tableName);
                rangeResult.setCreateTime(new Date());
                rangeResult.setHeight(oilHeight);
                rangeResult.setDeviceType(deviceRange.getDeviceType());
                rangeResult.setShopId(deviceRange.getShopId());
                rangeResult.setDeviceId(deviceRange.getId());
                rangeResult.setDataCode(dataCode);
                if(deviceRange.getIsEmpty() == 1) {
                    rangeResult.setStoreState(0);
                }else{
                    rangeResult.setStoreState(deviceRange.getStoreState());
                }
                rangeResult.setDeviceName(deviceRange.getDeviceName());
                rangeResult.setDeviceNum(deviceRange.getDeviceNum());
                rangeResult.setVolume(deviceRange.getLastVolumeNew());
                System.out.println("总重量：" + deviceRange.getTotalWeight());
                rangeResult.setWeight(MathUtil.getDoubleUpThree(deviceRange.getTotalWeight()));
                rangeResult.setTemperature(deviceRange.getTemperature());
                if(!deviceRange.getHumidity().contains("ME") && !deviceRange.getHumidity().contains("MS")){
                    rangeResult.setHumidity(deviceRange.getHumidity());
                }
                if(deviceRange.getLastOpUserId()!= null){
                    User user = userService.findById(deviceRange.getLastOpUserId());
                    if(user!= null){
                        rangeResult.setWxUserId(deviceRange.getLastOpUserId());
                        rangeResult.setIsTest(user.getIsTest());
                    }
                }
                ret = deviceRangeResultDao.insert(rangeResult);
                if(ret <= 0){
                    throw new TransactionalException("deviceRangeResultDao insert error");
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("addSingleRecord system error");
        }
        return ret;
    }


    @Override
    @Transactional
    public int addMultiplyRecord(String deviceNum, String[] dataArray, String data, String orderNum) {
        int ret = 0;
        try{
            String dataCode = "";
            DeviceRange deviceRange = deviceRangeService.getDeviceInfoByNum(deviceNum);
            if(deviceRange != null){
                dataCode = deviceRange.getDataCode();

                //判断当前是否需要重置 记录表
                String tableName = addNowMonthRecordTable();
                System.out.println("记录表名： " + tableName);
                if(StrUtil.isEmpty(tableName)){
                    return 0;
                }

                Map<String,Object> map = new HashMap<>();
                map.put("ck_device_range_record", tableName);
                RequestDataHelper.setRequestData(map);

                for (int i = 0; i < dataArray.length; i++){
                    DeviceRangeRecord record = new DeviceRangeRecord();

//                    record.setId(UuidUtil.get32UUID());
                    record.setDeviceId(deviceRange.getId());
                    record.setDataCode(dataCode);
                    record.setDeviceNum(deviceNum);
                    record.setCreateTime(new Date());
                    record.setOrderNum(orderNum);
                    //当前角度
                    record.setNowAngle(i + 1);
                    if(deviceRange.getErrorAngle() != null){
                        record.setVirtualAngle(i + 1 + deviceRange.getErrorAngle());
                    }
                    double errorHeight = 4d;
                    if(deviceRange.getErrorHeight()!= null){
                        errorHeight = deviceRange.getErrorHeight();
                    }
                    double bevel = Double.parseDouble(dataArray[i]) - errorHeight;
//                    bevel = bevel + 5;
                    //斜边长度  单位厘米   转换成  米
                    double nowBevel = MathUtil.getDouble(bevel / 100);
//                    System.out.println("雷达测量长度：" + nowBevel + "米");
                    record.setNowBevel(nowBevel);

                    //当前点和上一个点的斜率
                    record.setSlope(0d);
                    if(i > 0){
//                    k=(y2-y1)/(x2-x1)
                        double beforeBevel = Double.parseDouble(dataArray[i - 1]);
                        if(beforeBevel > 0){
                            double scope = Double.parseDouble(dataArray[i]) / beforeBevel;
                            record.setSlope(MathUtil.getDoubleUpFour(scope));
                        }
                    }

                    //计算出来的高度
                    double height = MathUtil.getVerticalLength(Double.parseDouble((i + 1) + ""), nowBevel);
                    record.setNowHeight(height);

                    //测量点的水平长度
                    double horizontal_length = MathUtil.getHorizontalLength(nowBevel, height);
                    record.setHorizontalLength(horizontal_length);


                    //仓半径
                    double rad = deviceRange.getStoreDiameter() / 2;
                    if(horizontal_length > rad){
                        //中心点右边，超过半径，需要用直径减去，计算 剩余的步长
                        record.setStepLength(Math.abs(horizontal_length - rad));
                    }else{
                        //中心点左边，计算出来的就是当前点的步长
                        record.setStepLength(Math.abs(rad - horizontal_length));
                    }

                    record.setReqDataStr(data);
                    ret = deviceRangeRecordDao.insert(record);
                    if(ret <= 0){
                        throw new TransactionalException("deviceRangeRecordDao insert error");
                    }
                }

                //判断当前这批数据上来的够不够90
                long recordCount = getRecordCount(deviceNum, dataCode);
                System.out.println("当前组数据数量：" + recordCount);
                if(recordCount >= 90){
                    // 寻找最长距离的那一个  点
                    DeviceRangeRecord maxLength = getMaxBevelByDeviceId(deviceNum, dataCode);
                    if(maxLength != null){
                        //根据最长距离的点，来计算 空余 整体体积
                        deviceRange = getLastEmptyVolume(maxLength,deviceRange,dataCode);
//                        deviceRange.setLastEmptyVolume(volume);
                        if(deviceRange.getIsEmpty() == 1){
                            deviceRange.setStoreState(0);
                        }
                        ret = deviceRangeService.resetDevice(deviceRange);
                        if(ret <= 0){
                            throw new TransactionalException("deviceRangeService resetDevice error");
                        }

                        DeviceRangeResult rangeResult = new DeviceRangeResult();
                        rangeResult.setRecordTableName(tableName);
                        rangeResult.setEffectiveAngle(deviceRange.getEffectiveAngle());
                        rangeResult.setCreateTime(new Date());
                        rangeResult.setShopId(deviceRange.getShopId());
                        rangeResult.setDeviceType(deviceRange.getDeviceType());
                        rangeResult.setDeviceId(deviceRange.getId());
                        rangeResult.setDataCode(dataCode);
                        if(deviceRange.getIsEmpty() == 1) {
                            rangeResult.setStoreState(0);
                        }else{
                            rangeResult.setStoreState(deviceRange.getStoreState());
                        }
                        rangeResult.setDeviceName(deviceRange.getDeviceName());
                        rangeResult.setDeviceNum(deviceRange.getDeviceNum());
                        rangeResult.setHeight(deviceRange.getAvgHeight());
                        rangeResult.setVolume(deviceRange.getLastVolumeNew());
                        System.out.println("总重量：" + deviceRange.getTotalWeight());
                        rangeResult.setWeight(MathUtil.getDoubleUpThree(deviceRange.getTotalWeight()));
                        rangeResult.setWeightNew(MathUtil.getDoubleUpThree(deviceRange.getNewMethodWeight()));

                        rangeResult.setTemperature(deviceRange.getTemperature());
                        if(!deviceRange.getHumidity().contains("ME") && !deviceRange.getHumidity().contains("MS")){
                            rangeResult.setHumidity(deviceRange.getHumidity());
                        }
                        rangeResult.setDataStr(data);

                        rangeResult.setMaxHeight(deviceRange.getMaxHeight());
                        rangeResult.setMinHeight(deviceRange.getMinHeight());
                        rangeResult.setLastHeight(deviceRange.getLastHeight());

                        if(deviceRange.getLastOpUserId()!= null){
                            User user = userService.findById(deviceRange.getLastOpUserId());
                            if(user!= null){
                                rangeResult.setWxUserId(deviceRange.getLastOpUserId());
                                rangeResult.setIsTest(user.getIsTest());
                            }
                        }


                        ret = deviceRangeResultDao.insert(rangeResult);
                        if(ret <= 0){
                            throw new TransactionalException("deviceRangeResultDao insert error");
                        }
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("addMultiplyRecord system error");
        }
        return ret;
    }



    @Override
    public String addNowMonthRecordTable() {
        String tableName = "";
        try {
            Parameter parameter = parameterService.getParameterById(1);
            if(parameter != null){
                if(StrUtil.isNotEmpty(parameter.getRangeRecordTableName())){
                    tableName = parameter.getRangeRecordTableName();
                    System.out.println("缓存记录表名：" + tableName);
                }

                String tableNameNow = "ck_device_range_record_" + DateUtil.getMonthSimpleStr(new Date());
                System.out.println("当前月份的表名：" + tableNameNow);

                if(!tableName.equals(tableNameNow)){
                    int isExits = deviceRangeResultDao.isTableExist(tableNameNow);
                    if(isExits == 0){
                        deviceRangeResultDao.createRecordTable(tableNameNow);

                        parameter.setRangeRecordTableName(tableNameNow);
                        parameterService.updateById(parameter);
                        parameterService.resetParameter(1);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableName;
    }

    /**
     *  粮仓  计算当前体积
     * @param maxLength
     * @param deviceRange
     * @param dataCode
     * @return
     */
    private DeviceRange getLastEmptyVolume(DeviceRangeRecord maxLength, DeviceRange deviceRange, String dataCode){


        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        double volume = 0d;
        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_id", deviceRange.getId());
        qw.eq("data_code", dataCode);
        qw.orderByAsc("now_angle");
//        deviceRange.setDataCode(dataCode);
        System.out.println("操作编码：" + dataCode);

        //距离最长的边所对应的高度
//        double maxHeight = maxLength.getNowHeight();// MathUtil.getVerticalLength(maxLength.getNowAngle(),maxLength.getNowBevel());

        //记录饲料已经到 圆锥体里面的 空余空间的高度值，方便计算体积
        List<Double> coneHeightList = new ArrayList<>();


        double lastSlope = 0d;

        //最开始的测量记录
        DeviceRangeRecord firstRecord = getLastRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,1,tableName);
        if(firstRecord != null){
            deviceRange.setFirstBevel(firstRecord.getNowBevel());
            System.out.println("最开始的测量记录: 角度" + firstRecord.getNowAngle()+ "，最长边：" + firstRecord.getNowBevel() + " , 对应高度：" + firstRecord.getNowHeight());
        }

        //最后对应额斜边记录
        DeviceRangeRecord lastRecord = getLastRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,0,tableName);
        if(lastRecord != null){
            deviceRange.setLastBevel(lastRecord.getNowBevel());
            System.out.println("最后斜边记录: 角度" + lastRecord.getNowAngle()+ "，最长边：" + lastRecord.getNowBevel() + " , 对应高度：" + lastRecord.getNowHeight());
        }else{
            return deviceRange;
        }


        double maxAngle = MathUtil.getAngleByBevel(lastRecord.getNowHeight(), deviceRange.getStoreDiameter());
        System.out.println("当前获取的 取值角度：" + Math.round(maxAngle));
        deviceRange.setEffectiveAngle(maxAngle);

        List<DeviceRangeRecord> computeRecords = new ArrayList<>();
        List<DeviceRangeRecord> records = deviceRangeRecordDao.selectList(qw);
        if(CollUtil.isNotEmpty(records)){
            int index = 0;
            for (DeviceRangeRecord record : records){

                //右下角 角度对应的往后的度数的数据
                if(record.getNowAngle() >= Math.round(maxAngle)) {
                    if(record.getSlope() >= 0.8 && record.getSlope() <= 1.2){
                        computeRecords.add(record);//获取 参与计算的数据
                    }
                }
                //测量点的水平长度
                double horizontal_length = MathUtil.getHorizontalLength(record.getNowBevel(), record.getNowHeight());
                record.setHorizontalLength(horizontal_length);
//
//                //仓半径
                double rad = deviceRange.getStoreDiameter() / 2;
                if(horizontal_length >= rad){
                    //中心点右边，超过半径，需要用直径减去，计算 剩余的步长
//                    record.setStepLength(Math.abs(deviceRange.getStoreDiameter() - horizontal_length));
                    record.setStepLength(Math.abs(horizontal_length - rad));
                }else{
                    //中心点左边，计算出来的就是当前点的步长
                    record.setStepLength(Math.abs(rad - horizontal_length));
                }

//                record.setSlope(0d);
//                if(index > 0){
//                    DeviceRangeRecord recordBefore = records.get(index - 1);
//                    //当前点和上一个点的斜率
//                    if(index > 0){
////                    k=(y2-y1)/(x2-x1)
//                        double beforeBevel = recordBefore.getNowBevel();
//                        if(beforeBevel > 0){
//                            double scope = record.getNowBevel() / beforeBevel;
//                            record.setSlope(MathUtil.getDoubleUpFour(scope));
//                        }
//                    }
//                }
//                deviceRangeRecordDao.updateById(record);

                index++;
            }
        }

        List<DeviceRangeRecord> maxHeightRecords = getMaxHeightRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,maxAngle,10);
        //当前有效数据
        List<DeviceRangeRecord> computeRecordsNew  = new ArrayList<>();
        for(DeviceRangeRecord rangeRecord: computeRecords){
            boolean bl = false;
            //排除最高的几组数据
            for (DeviceRangeRecord rangeRecordMax : maxHeightRecords){
                int nowAngle = rangeRecord.getNowAngle();
                int maxNowAngle = rangeRecordMax.getNowAngle();
                if(nowAngle == maxNowAngle){
                    bl = true;
                }
            }

            if(!bl || (deviceRange.getShopId() == 43 && rangeRecord.getNowAngle() >= 80)){
                if(rangeRecord.getNowBevel() > 0){
                    computeRecordsNew.add(rangeRecord);
                    double height = MathUtil.getVerticalLength(rangeRecord.getNowAngle(), rangeRecord.getNowBevel());
                    //圆柱部分高度
                    if(height > deviceRange.getCylinderHeight()){
                        double coneHeight = height - deviceRange.getCylinderHeight();
                        coneHeightList.add(coneHeight);
                    }
                }
            }
        }


        double maxHeight = 0;
        DeviceRangeRecord maxHeightRecord = getMaxHeightByDeviceId(deviceRange.getDeviceNum(), dataCode,tableName);
//        DeviceRangeRecord maxHeightRecord = getMaxHeightByComputeRecords(computeRecordsNew);
        if(maxHeightRecord != null){
            System.out.println("测量转换最大高度记录: 角度" + maxHeightRecord.getNowAngle() + "， 斜边长：" + maxHeightRecord.getNowBevel() + " , 对应高度：" + maxHeightRecord.getNowHeight());
            maxHeight = maxHeightRecord.getNowHeight();
            deviceRange.setMaxHeight(maxHeightRecord.getNowHeight());
        }
        DeviceRangeRecord minHeightRecord = getMinHeightByComputeRecords(deviceRange, computeRecordsNew);
//        if(computeRecordsNew.size() > 0){
//            minHeightRecord = getMinHeightByComputeRecords(deviceRange, computeRecordsNew);
//        }else{
//            minHeightRecord = getMinHeightByComputeRecords(deviceRange, computeRecords);
//        }

        if(minHeightRecord != null){
            deviceRange.setMinHeight(minHeightRecord.getNowHeight());
            System.out.println("测量转换最小高度记录: 角度" + minHeightRecord.getNowAngle() + "，斜边长：" + minHeightRecord.getNowBevel() + " , 对应高度：" + minHeightRecord.getNowHeight());
        }else{
            return deviceRange;
        }

        deviceRange.setLastHeight(lastRecord.getNowHeight());

        double lastHeight = getLastAvgHeight(computeRecordsNew,3);
        double tempValue = (lastRecord.getNowHeight() - lastHeight) * 100;
        if(Math.abs(tempValue) >= 10){//最后一个数和 最后3个数的平均数相差超过15厘米，就取最后一个数作为最后高度
            lastHeight = lastRecord.getNowHeight();
        }
        deviceRange.setAvgHeight(lastHeight);

        //筒仓  满仓状态  0 -  空仓  1 -  正常状态 2 - 满仓
        deviceRange.setStoreState(1);
        //判断满仓

//        double ss1 = deviceRange.getCylinderHeight() - ;
        if(lastHeight < 2){
            deviceRange.setStoreState(2);
            System.out.println("满仓状态");
        }
        double ss = deviceRange.getCylinderHeight() - lastHeight;
        if(ss <= 1){
            deviceRange.setStoreState(0);
            System.out.println("空仓状态");
            //发送 空仓的 推送消息
            sendWxMsg(deviceRange);
        }

        //上锥最短的斜边对应的记录
//        DeviceRangeRecord minBevelRecord = getMinBevelByDeviceId(deviceRange.getDeviceNum(), dataCode,maxAngle);
        DeviceRangeRecord minBevelRecord = getMinBevelByComputeRecords(computeRecordsNew);
//        DeviceRangeRecord minBevelRecord = getMinBevelByDeviceId(computeRecords);
        if(minBevelRecord!=null){
            System.out.println("上锥最短的斜边对应的记录: 角度" + minBevelRecord.getNowAngle() + "，最短边：" + minBevelRecord.getNowBevel() + " , 对应高度：" + minBevelRecord.getNowHeight());
        }
        //最长边对应的斜边记录
//        DeviceRangeRecord maxBevelRecord = getMaxBevelByDeviceId(deviceRange.getDeviceNum(), dataCode);
//        DeviceRangeRecord maxBevelRecord = getMaxBevelByDeviceId(computeRecords);
//        if(maxBevelRecord!= null){
//            System.out.println("最长边对应的斜边记录: 角度" + maxBevelRecord.getNowAngle()+ "，最长边：" + maxBevelRecord.getNowBevel() + " , 对应高度：" + maxBevelRecord.getNowHeight());
//        }

        double emptyConeVolume = 0d;
        //   舱内形状
        int shapeType = 0;

        // 最长边 对应的高度减去  最后一条对应的高度
        double heightAo = maxHeightRecord.getNowHeight() - lastHeight;
        System.out.println("凹差值：" + heightAo);
        double heightTu = 0;//lastRecord.getNowHeight() - minHeightRecord.getNowHeight();
        if(minHeightRecord!= null){
            heightTu = lastHeight - minHeightRecord.getNowHeight();
        }
        System.out.println("凸差值：" + heightTu);


        //最后高度对应的空余体积
        double lastVolumeNew = 0d;// getCylinderVolume(deviceRange, lastHeight);
        if(deviceRange.getIsEllipse() == 2){
            System.out.println("四方形柱体 体积:" + lastVolumeNew);
            lastVolumeNew = getRectVolume(deviceRange, lastHeight);
        }else{
            lastVolumeNew = getCylinderVolume(deviceRange, lastHeight);
        }

        deviceRange.setLastHeightVolume(lastVolumeNew);

//        System.out.println("maxHeightRecord.getNowHeight(): " + maxHeightRecord.getNowHeight());
//        System.out.println(" lastHeight : " + lastHeight);
//        if(minHeightRecord!= null){
//            System.out.println("minHeightRecord.getNowHeight(): " + minHeightRecord.getNowHeight());
//        }
//        if(minBevelRecord!=null){
//            System.out.println("minBevelRecord.getNowHeight(): " + minBevelRecord.getNowHeight());
//        }

        //凹型
        double volume1 = 0d;
        if(maxHeightRecord.getNowHeight() - lastHeight >= deviceRange.getHeightDifference()){
            shapeType = 2;
            // 凹处下锥的空余体积
            emptyConeVolume = getEmptyLowerConeVolume(deviceRange,dataCode,computeRecordsNew,tableName);

            deviceRange.setConcaveConvexVolume(emptyConeVolume);
            System.out.println("粮食堆形状：凹的，椎体体积：" + emptyConeVolume);
            // 下锥空余体积 + 最后高度对应体积  = 舱内整个的空余体积
            volume1 = lastVolumeNew + emptyConeVolume;
            System.out.println("空余部分对应的体积:" + volume1);

//            deviceRange.setLastVolumeNew(volume1);
//            deviceRange.setLastVolume(volume1);
            double addVolume = 0;// (deviceRange.getMaxVolume() - volume1) * 5.5 /100;
            System.out.println("最后粮食剩余体积 lastVolumeNew：" + (deviceRange.getMaxVolume() - volume1 + addVolume));
            deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - volume1 + addVolume));
        } else{
            if(lastHeight - minHeightRecord.getNowHeight() >= deviceRange.getHeightDifference() ){//凸的
                shapeType = 1;
                emptyConeVolume = getConeVolumeByRecord(deviceRange,heightTu);
                deviceRange.setConcaveConvexVolume(emptyConeVolume);
                System.out.println("粮食堆形状：凸的，椎体体积：" + emptyConeVolume);
                volume1 = lastVolumeNew - emptyConeVolume;

                System.out.println("空余部分对应的体积:" + volume1);
//                deviceRange.setLastVolumeNew(volume1);
//                deviceRange.setLastVolume(volume1);
//                System.out.println("最后椎体体积：" + volume1);
                double addVolume = 0;//
                // (deviceRange.getMaxVolume() - volume1) * 5.5 /100;
                System.out.println("最后粮食剩余体积 lastVolumeNew：" + (deviceRange.getMaxVolume() - volume1 + addVolume));
                deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - volume1 + addVolume));
            }else{
                emptyConeVolume = getConeVolumeByRecord(deviceRange,heightTu);
                System.out.println("粮食堆形状：平的，椎体体积：" + emptyConeVolume);
                deviceRange.setConcaveConvexVolume(emptyConeVolume);

                volume1 = lastVolumeNew;
                System.out.println("空余部分对应的体积:" + lastVolumeNew);

                double addVolume = 0;//  (deviceRange.getMaxVolume() - lastVolumeNew) * 5.5 /100;
                System.out.println("最后粮食剩余体积 lastVolumeNew：" + (deviceRange.getMaxVolume() - lastVolumeNew + addVolume));
//            double volume1 = lastVolumeNew + emptyConeVolume;
                deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - lastVolumeNew + addVolume));
                deviceRange.setLastVolume((deviceRange.getMaxVolume() - lastVolumeNew + addVolume));
            }
        }


        double tempVolume = getVolumeByComputeRecords(deviceRange, computeRecordsNew);
        System.out.println("空余部分对应的体积 最新：" + tempVolume);


        double newMethodWeight = (volume1 - tempVolume) * deviceRange.getPlotRatio();
        System.out.println("新算法和老算法的差值，千克数：" + newMethodWeight);
        deviceRange.setNewMethodWeight(newMethodWeight);


//        double tempVolumeTest = getVolumeOpTest();
//        System.out.println("空余部分体积 测试：" + tempVolumeTest);

//        double tempVolumeTest = getVolumeOpTest();
//        System.out.println("空余部分对应的体积 test：" + tempVolumeTest);


        deviceRange.setShapeType(shapeType);

//        List<Double> heights = new ArrayList<>();
        if(CollUtil.isNotEmpty(computeRecordsNew)){
//            double totalHeight = 0d;
//            for (DeviceRangeRecord record : computeRecordsNew){
//                totalHeight += record.getNowHeight().doubleValue();
//                heights.add(record.getNowHeight());
//            }
            //平均高度
//            System.out.println("筒仓高度：" + deviceRange.getCylinderHeight());
//            System.out.println("筒仓半径 = " + (deviceRange.getStoreDiameter() / 2) + "米");
//            System.out.println("椎体高度：" + deviceRange.getConeHeight());
//            System.out.println("有效高度总和：" + totalHeight);
//            System.out.println("有效高度数量：" + heights.size());
//            double avgHeight = MathUtil.getDoubleUpThree(totalHeight / heights.size());
//            System.out.println("圆柱的平均高度：" + avgHeight + "米");
//            deviceRange.setAvgHeight(avgHeight);

            //创建圆柱体对象
//            volume = getCylinderVolume(deviceRange,avgHeight);
            volume = deviceRange.getLastVolumeNew();

            System.out.println("剩余粮食的体积：" + volume);




//            Cylinder volu = new Cylinder();
//            volu.setIsEllipse(deviceRange.getIsEllipse());
//            if(deviceRange.getIsEllipse() == 1){
//                volu.setLongHalf(deviceRange.getLongHalfShaft());
//                volu.setShortHalf(deviceRange.getShortHalfShaft());
//            }
//            //给半径和高赋值
//            volu.setRad(deviceRange.getStoreDiameter() / 2);
//            volu.setHeight(avgHeight);
//            //输出
//            System.out.println("筒仓底面半径 = " + volu.getRad() + "米");
//            System.out.println("圆柱的高 = " + volu.getHeight()+ "米");
//            //调用方法直接输出底面积
//            volu.area();
//            volume = volu.volume();
            //当前剩余饲料的体积数 = 总体积 - 空余体积
            System.out.println("总体积 maxVolume:" + (deviceRange.getMaxVolume()));
            System.out.println("圆柱总体积 maxCylinderVolume:" + (deviceRange.getMaxCylinderVolume()));
            System.out.println("圆锥体总体积 maxConeVolume :" + (deviceRange.getMaxConeVolume()));
            //调用方法输出圆柱体体积
            System.out.println("圆柱体体积(空余) = " + (deviceRange.getMaxVolume() - volume));

            //空余体积
            deviceRange.setLastEmptyVolume(deviceRange.getMaxVolume() - volume);

            //
            System.out.println("当前剩余饲料的体积数:" + volume);
            System.out.println("容重 = " + deviceRange.getPlotRatio());
            //包含下方椎体的体积
            double totalVolume = volume;// deviceRange.getMaxVolume() - volume;
//            deviceRange.setLastVolume(totalVolume);

            double totalWeight = totalVolume * deviceRange.getPlotRatio();
            /**
             *  额外的系数  容重
             */
            if(deviceRange.getExtendRatio()!=null && deviceRange.getExtendRatio() > 0){
                totalWeight = totalWeight * deviceRange.getExtendRatio();
            }
            System.out.println("总重量（圆柱部分+圆锥部分）数据处理前：" + totalWeight);
            deviceRange.setTotalWeight(totalWeight);

            if(shapeType == 0){// 平的
//                deviceRange.setTotalWeight(totalWeight);
            } else if(shapeType == 1){//凸的
                if(deviceRange.getBulgeKg()!= null){
                    totalWeight += deviceRange.getBulgeKg();
                }
            } else if(shapeType == 2){//凹的
                if(deviceRange.getConcaveKg()!= null){
                    totalWeight += deviceRange.getConcaveKg();
                }
            }

            if(totalWeight < 0) {
                totalWeight = 0;
            }

            deviceRange.setTotalWeight(totalWeight);
            System.out.println("总重量（圆柱部分+圆锥部分）数据处理后：" + totalWeight);

            //当前计算出来的 高度如果是 大于 圆柱筒高
//            if(maxHeight > deviceRange.getCylinderHeight()){
//                if(CollUtil.isNotEmpty(coneHeightList)){
//                    double totalConeHeight = 0d;
//                    for (Double height : coneHeightList){
//                        totalConeHeight += height;
//                        heights.add(height);
//                    }
//                    //平均高度
//                    double avgConeHeight = MathUtil.getDoubleUpThree(totalConeHeight / heights.size());
//                    System.out.println("圆锥的打点平均高度： " + avgConeHeight);
//
//                    //下方椎体的饲料体积
//                    //double store_radius, double cone_height,double height
//                    if(avgConeHeight > 0){
//                        double coneVolume = MathUtil.getConeVolumeByHeight(deviceRange,avgConeHeight);
//                        System.out.println("下方椎体的饲料体积： " + coneVolume);
//
//                        //当前剩余饲料的体积数 = 总体积 - 空余体积
//                        deviceRange.setLastVolume(coneVolume);
//
//                        totalWeight = coneVolume * deviceRange.getPlotRatio();
//                        if(deviceRange.getExtendRatio()!=null && deviceRange.getExtendRatio() > 0){
//                            totalWeight = totalWeight * deviceRange.getExtendRatio();
//                        }
//                        System.out.println("总重量（圆锥部分）：" + totalWeight);
//                        deviceRange.setTotalWeight(totalWeight);
//                    }
//                }
//            }
        }
        deviceRange.setLastComputeTime(new Date());
        return deviceRange;
    }


    /**
     *  粮仓  计算当前体积  积分算法
     * @param deviceRange
     * @param dataCode
     * @return
     */
    private DeviceRange getLastEmptyVolumeNew(DeviceRange deviceRange, String dataCode){


        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        double volume = 0d;
        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_id", deviceRange.getId());
        qw.eq("data_code", dataCode);
        qw.orderByAsc("now_angle");
        System.out.println("操作编码：" + dataCode);

        //记录饲料已经到 圆锥体里面的 空余空间的高度值，方便计算体积
        List<Double> coneHeightList = new ArrayList<>();
        //最开始的测量记录
        DeviceRangeRecord firstRecord = getLastRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,1,tableName);
        if(firstRecord != null){
            deviceRange.setFirstBevel(firstRecord.getNowBevel());
            System.out.println("最开始的测量记录: 角度" + firstRecord.getNowAngle()+ "，最长边：" + firstRecord.getNowBevel() + " , 对应高度：" + firstRecord.getNowHeight());
        }

        //最后对应额斜边记录
        DeviceRangeRecord lastRecord = getLastRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,0,tableName);
        if(lastRecord != null){
            deviceRange.setLastBevel(lastRecord.getNowBevel());
            System.out.println("最后斜边记录: 角度" + lastRecord.getNowAngle()+ "，最长边：" + lastRecord.getNowBevel() + " , 对应高度：" + lastRecord.getNowHeight());
        }else{
            return deviceRange;
        }

        double maxAngle = MathUtil.getAngleByBevel(lastRecord.getNowHeight(), deviceRange.getStoreDiameter());
        System.out.println("当前获取的 取值角度：" + Math.round(maxAngle));
        deviceRange.setEffectiveAngle(maxAngle);

        List<DeviceRangeRecord> computeRecords = new ArrayList<>();
        List<DeviceRangeRecord> records = deviceRangeRecordDao.selectList(qw);
        if(CollUtil.isNotEmpty(records)){
            int index = 0;
            for (DeviceRangeRecord record : records){
                //右下角 角度对应的往后的度数的数据
                if(record.getNowAngle() >= Math.round(maxAngle)) {
                    if(record.getSlope() >= 0.8 && record.getSlope() <= 1.2){
                        computeRecords.add(record);//获取 参与计算的数据
                    }
                }
                index++;
            }
        }

        List<DeviceRangeRecord> maxHeightRecords = getMaxHeightRecordByDeviceId(deviceRange.getDeviceNum(),dataCode,maxAngle,10);
        //当前有效数据
        List<DeviceRangeRecord> computeRecordsNew  = new ArrayList<>();
        for(DeviceRangeRecord rangeRecord: computeRecords){
            boolean bl = false;
            //排除最高的几组数据
            for (DeviceRangeRecord rangeRecordMax : maxHeightRecords){
                int nowAngle = rangeRecord.getNowAngle();
                int maxNowAngle = rangeRecordMax.getNowAngle();
                if(nowAngle == maxNowAngle){
                    bl = true;
                }
            }

            if(!bl || (deviceRange.getShopId() == 43 && rangeRecord.getNowAngle() >= 80)){
                if(rangeRecord.getNowBevel() > 0){
                    computeRecordsNew.add(rangeRecord);
                    double height = MathUtil.getVerticalLength(rangeRecord.getNowAngle(), rangeRecord.getNowBevel());
                    //圆柱部分高度
                    if(height > deviceRange.getCylinderHeight()){
                        double coneHeight = height - deviceRange.getCylinderHeight();
                        coneHeightList.add(coneHeight);
                    }
                }
            }
        }

        DeviceRangeRecord maxHeightRecord = getMaxHeightByDeviceId(deviceRange.getDeviceNum(), dataCode, tableName);
        if(maxHeightRecord != null){
            System.out.println("测量转换最大高度记录: 角度" + maxHeightRecord.getNowAngle() + "， 斜边长：" + maxHeightRecord.getNowBevel() + " , 对应高度：" + maxHeightRecord.getNowHeight());
            deviceRange.setMaxHeight(maxHeightRecord.getNowHeight());
        }
        DeviceRangeRecord minHeightRecord = getMinHeightByComputeRecords(deviceRange, computeRecordsNew);

        if(minHeightRecord != null){
            deviceRange.setMinHeight(minHeightRecord.getNowHeight());
            System.out.println("测量转换最小高度记录: 角度" + minHeightRecord.getNowAngle() + "，斜边长：" + minHeightRecord.getNowBevel() + " , 对应高度：" + minHeightRecord.getNowHeight());
        }else{
            return deviceRange;
        }

        deviceRange.setLastHeight(lastRecord.getNowHeight());

        double lastHeight = getLastAvgHeight(computeRecordsNew,3);
        double tempValue = (lastRecord.getNowHeight() - lastHeight) * 100;
        if(Math.abs(tempValue) >= 10){//最后一个数和 最后3个数的平均数相差超过15厘米，就取最后一个数作为最后高度
            lastHeight = lastRecord.getNowHeight();
        }
        deviceRange.setAvgHeight(lastHeight);

        //筒仓  满仓状态  0 -  空仓  1 -  正常状态 2 - 满仓
        deviceRange.setStoreState(1);
        //判断满仓
        if(lastHeight < 2){
            deviceRange.setStoreState(2);
            System.out.println("满仓状态");
        }
        double ss = deviceRange.getCylinderHeight() - lastHeight;
        if(ss <= 1){
            deviceRange.setStoreState(0);
            System.out.println("空仓状态");
            //发送 空仓的 推送消息
            sendWxMsg(deviceRange);
        }

        //上锥最短的斜边对应的记录
        DeviceRangeRecord minBevelRecord = getMinBevelByComputeRecords(computeRecordsNew);
        if(minBevelRecord!=null){
            System.out.println("上锥最短的斜边对应的记录: 角度" + minBevelRecord.getNowAngle() + "，最短边：" + minBevelRecord.getNowBevel() + " , 对应高度：" + minBevelRecord.getNowHeight());
        }

        double emptyConeVolume = 0d;
        //   舱内形状
        int shapeType = 0;

        // 最长边 对应的高度减去  最后一条对应的高度
        double heightAo = maxHeightRecord.getNowHeight() - lastHeight;
        System.out.println("凹差值：" + heightAo);
        double heightTu = 0;//lastRecord.getNowHeight() - minHeightRecord.getNowHeight();
        if(minHeightRecord!= null){
            heightTu = lastHeight - minHeightRecord.getNowHeight();
        }
        System.out.println("凸差值：" + heightTu);


        //最后高度对应的空余体积
        double lastVolumeNew = 0d;// getCylinderVolume(deviceRange, lastHeight);
        if(deviceRange.getIsEllipse() == 2){
            System.out.println("四方形柱体 体积:" + lastVolumeNew);
            lastVolumeNew = getRectVolume(deviceRange, lastHeight);
        }else{
            lastVolumeNew = getCylinderVolume(deviceRange, lastHeight);
        }
        System.out.println("最后高度对应的体积:" + lastVolumeNew);

        deviceRange.setLastHeightVolume(lastVolumeNew);

        //凹型
        if(maxHeightRecord.getNowHeight() - lastHeight >= deviceRange.getHeightDifference()){
            shapeType = 2;
            // 凹处下锥的空余体积
            emptyConeVolume = getEmptyLowerConeVolume(deviceRange,dataCode,computeRecordsNew, tableName);

            deviceRange.setConcaveConvexVolume(emptyConeVolume);
            System.out.println("粮食堆形状：凹的，椎体体积：" + emptyConeVolume);
            // 下锥空余体积 + 最后高度对应体积  = 舱内整个的空余体积
            double volume1 = lastVolumeNew + emptyConeVolume;
            double addVolume = 0;// (deviceRange.getMaxVolume() - volume1) * 5.5 /100;
            System.out.println("最后体积：" + (deviceRange.getMaxVolume() - volume1 + addVolume));
            deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - volume1 + addVolume));
        } else{
            if(lastHeight - minHeightRecord.getNowHeight() >= deviceRange.getHeightDifference() ){//凸的
                shapeType = 1;
                emptyConeVolume = getConeVolumeByRecord(deviceRange,heightTu);
                deviceRange.setConcaveConvexVolume(emptyConeVolume);
                System.out.println("粮食堆形状：凸的，椎体体积：" + emptyConeVolume);
                double volume1 = lastVolumeNew - emptyConeVolume;
                double addVolume = 0;//
                System.out.println("最后体积：" + (deviceRange.getMaxVolume() - volume1 + addVolume));
                deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - volume1 + addVolume));
            }else{
                emptyConeVolume = getConeVolumeByRecord(deviceRange,heightTu);
                System.out.println("粮食堆形状：平的，椎体体积：" + emptyConeVolume);
                deviceRange.setConcaveConvexVolume(emptyConeVolume);
                double addVolume = 0;//  (deviceRange.getMaxVolume() - lastVolumeNew) * 5.5 /100;
                System.out.println("最后体积：" + (deviceRange.getMaxVolume() - lastVolumeNew + addVolume));

                deviceRange.setLastVolumeNew((deviceRange.getMaxVolume() - lastVolumeNew + addVolume));
                deviceRange.setLastVolume((deviceRange.getMaxVolume() - lastVolumeNew + addVolume));
            }
        }

        deviceRange.setShapeType(shapeType);

        if(CollUtil.isNotEmpty(computeRecordsNew)){
            //创建圆柱体对象
            volume = deviceRange.getLastVolumeNew();
            //当前剩余饲料的体积数 = 总体积 - 空余体积
            System.out.println("总体积:" + (deviceRange.getMaxVolume()));
            System.out.println("圆柱总体积:" + (deviceRange.getMaxCylinderVolume()));
            System.out.println("圆锥体总体积:" + (deviceRange.getMaxConeVolume()));
            //调用方法输出圆柱体体积
            System.out.println("圆柱体体积(空余) = " + (deviceRange.getMaxVolume() - volume));

            //空余体积
            deviceRange.setLastEmptyVolume(deviceRange.getMaxVolume() - volume);

            //
            System.out.println("当前剩余饲料的体积数:" + volume);
            System.out.println("容重 = " + deviceRange.getPlotRatio());
            //包含下方椎体的体积
            double totalVolume = volume;

            double totalWeight = totalVolume * deviceRange.getPlotRatio();
            /**
             *  额外的系数  容重
             */
            if(deviceRange.getExtendRatio()!=null && deviceRange.getExtendRatio() > 0){
                totalWeight = totalWeight * deviceRange.getExtendRatio();
            }
            System.out.println("总重量（圆柱部分+圆锥部分）数据处理前：" + totalWeight);
            deviceRange.setTotalWeight(totalWeight);

            if(shapeType == 0){// 平的
            } else if(shapeType == 1){//凸的
                if(deviceRange.getBulgeKg()!= null){
                    totalWeight += deviceRange.getBulgeKg();
                }
            } else if(shapeType == 2){//凹的
                if(deviceRange.getConcaveKg()!= null){
                    totalWeight += deviceRange.getConcaveKg();
                }
            }

            if(totalWeight < 0) {
                totalWeight = 0;
            }

            deviceRange.setTotalWeight(totalWeight);
            System.out.println("总重量（圆柱部分+圆锥部分）数据处理后：" + totalWeight);
        }
        deviceRange.setLastComputeTime(new Date());
        return deviceRange;
    }

    private double getVolumeByComputeRecords(DeviceRange deviceRange, List<DeviceRangeRecord> computeRecordsNew){

        //半径
        double radMiddle = deviceRange.getStoreDiameter() / 2;

        //总体积
        double volumeCount = 0d;
//        List<DeviceRangeRecord> leftRecord = new ArrayList<>();
//        List<DeviceRangeRecord> rightRecord = new ArrayList<>();
        System.out.println("有效数据数量： " + computeRecordsNew.size());


        List<DeviceRangeRecord> tempRecords = new ArrayList<>();
        DeviceRangeRecord first = computeRecordsNew.get(0);
        first.setStepLength(radMiddle);
        tempRecords.add(first);
        tempRecords.addAll(computeRecordsNew);


        //先分为 左右2部分
//        for (DeviceRangeRecord record : tempRecords){
//            if(record.getHorizontalLength() >= radMiddle){
//                leftRecord.add(record);
//            }else{
//                rightRecord.add(record);
//            }
//        }

        volumeCount += getVolumeOp(radMiddle, tempRecords, 0);
//        volumeCount += getVolumeOp(radMiddle, leftRecord, 0);

//        volumeCount += getVolumeOp(radMiddle, rightRecord, 1);

        return volumeCount;
    }


    /**
     *
     * @param radMiddle
     * @param leftRecord
     * @param type  0 - 右半部分  1 - 左半部分
     * @return
     */
    private double getVolumeOp(double radMiddle, List<DeviceRangeRecord> leftRecord, int type){
        double volumeCount = 0d;
        int index = 0;
        for (DeviceRangeRecord record : leftRecord){
            double volume = 0d;
            DeviceRangeRecord recordNext = leftRecord.get(index + 1);
//            System.out.println("有效数据数量：index + 1 = " + (index + 1));
//            if(index == 0 && type == 0) {
//                //左边部分
//                double height = record.getNowHeight();
//                // 第一组，外圆用 半径算
//                double rad = radMiddle;
//                double volumeTemp = MathUtil.getDoubleUpThree(Math.PI * rad * rad) * height;
////                System.out.println("外 半径： " + radMiddle + ", 体积： " + volumeTemp);
//
//                //内圆是第一组数据
//                double radNext = record.getStepLength();
//
//                double volumeNext = MathUtil.getDoubleUpThree(Math.PI * radNext * radNext) * height;
////                System.out.println("内 半径： " + radNext + ", 体积： " + volumeNext);
//
//                volume = (Math.abs(volumeTemp - volumeNext)) / 2;
//
////                System.out.println("第 " + (index + 1) +"组体积差： " + volume);
//            } else {//其他部分
                double height = (record.getNowHeight() + recordNext.getNowHeight()) / 2;
                // 第一组，外圆用 半径算
                double rad = record.getStepLength();
                double volumeTemp = MathUtil.getDoubleUpThree(Math.PI * rad * rad) * height;
//                System.out.println("外 半径： " + rad + ", 体积： " + volumeTemp);

                //内圆是第一组数据
                double radNext = recordNext.getStepLength();

                double volumeNext = MathUtil.getDoubleUpThree(Math.PI * radNext * radNext) * height;

                volume = (Math.abs(volumeTemp - volumeNext)) / 2;
//                System.out.println("内 半径： " + radNext + ", 体积： " + volumeNext);

//                System.out.println("半径差：" + Math.abs(rad - radNext) + " 体积： " + volume);
//                System.out.println("第 " + (index + 1) +"组体积差： " + volume);
//            }

            volumeCount+= volume;

            index ++;

            if(index + 1 == leftRecord.size()){
                break;
            }
        }
        return volumeCount;
    }



    /**
     *
     * @return
     */
    private double getVolumeOpTest(){
        List<DeviceRangeRecord> leftRecord = new ArrayList<>();
//      4.1,2.6,     5.2,,3.9, 5d, 1.3,0d,1d,2.9,6.5
        Double[] steps =  {6.5, } ;
        for (int i = 0;i < steps.length;i++){
            DeviceRangeRecord record = new DeviceRangeRecord();
            record.setNowHeight(13d);
            record.setStepLength(steps[i]);
            leftRecord.add(record);
        }


        double volumeCount = 0d;
        int index = 0;
        for (DeviceRangeRecord record : leftRecord){
            double volume = 0d;
            DeviceRangeRecord recordNext = leftRecord.get(index + 1);
            double height = (record.getNowHeight() + recordNext.getNowHeight()) / 2;
            // 第一组，外圆用 半径算
            double rad = record.getStepLength();
            double volumeTemp = MathUtil.getDoubleUpThree(Math.PI * rad * rad) * height;
            System.out.println("外 半径： " + rad + ", 体积： " + volumeTemp);

            //内圆是第一组数据
            double radNext = recordNext.getStepLength();

            double volumeNext = MathUtil.getDoubleUpThree(Math.PI * radNext * radNext) * height;
            System.out.println("内 半径： " + radNext + ", 体积： " + volumeNext);

            volume = (Math.abs(volumeTemp - volumeNext)) / 2;

//            System.out.println("第 " + (index + 1) +"组体积差： " + volume);
            System.out.println("半径差：" + Math.abs(rad - radNext) + " 体积： " + volume);



            volumeCount+= volume;

            index ++;

            if(index + 1 == leftRecord.size()){
                break;
            }
        }
        return volumeCount;
    }




    /**
     *  油罐 计算当前体积
     * @param oilHeight
     * @param deviceRange
     * @return
     */
    private DeviceRange getLastEmptyVolumeOil(double oilHeight, DeviceRange deviceRange){
        double volume = 0d;

        deviceRange.setLastComputeTime(new Date());

        if(deviceRange.getIsEllipse() == 2){

            System.out.println("液面高度：" + oilHeight);
            Rect rect = new Rect();
            rect.setLength(deviceRange.getRectLength());
            rect.setWidth(deviceRange.getRectWidth());
            rect.setHeight(oilHeight);
            volume = rect.volume();
            System.out.println("油罐计算出体积：" + volume);

        }else{

            Cylinder cylinder = new Cylinder();
            cylinder.setIsEllipse(deviceRange.getIsEllipse());
            cylinder.setIsLie(deviceRange.getIsLie());
            //是否是椭圆  0 - 正圆   1 - 椭圆 - 2 卧式正圆  3 - 卧式椭圆
            if(deviceRange.getIsLie()!= null && deviceRange.getIsLie() == 1){
                cylinder.setHeight(deviceRange.getCylinderHeight());
                System.out.println("卧式圆柱高度：" + deviceRange.getCylinderHeight());
                cylinder.setMeasureHeight(oilHeight);
                System.out.println("卧式液位高度：" + oilHeight);
            }else{
                cylinder.setHeight(oilHeight);
            }
            System.out.println("液面高度：" + oilHeight);
            if(deviceRange.getIsEllipse()== 1){
                cylinder.setShortHalf(deviceRange.getShortHalfShaft());
                cylinder.setLongHalf(deviceRange.getLongHalfShaft());
            }
            //半径
            cylinder.setRad(deviceRange.getStoreDiameter() / 2);
            System.out.println("油罐半径：" + (deviceRange.getStoreDiameter() / 2));
            volume = cylinder.volume();

            System.out.println("油罐计算出体积：" + volume);
        }


        deviceRange.setAvgHeight(oilHeight);
        deviceRange.setLastVolumeNew(volume);
        deviceRange.setLastVolume(volume);
        deviceRange.setFirstBevel(oilHeight);
        deviceRange.setLastBevel(oilHeight);
        deviceRange.setLastEmptyVolume(deviceRange.getMaxVolume() - volume);
        System.out.println("空闲体积：" + (deviceRange.getMaxVolume() - volume) + "m³");
        System.out.println("容重比：" + deviceRange.getPlotRatio());


        double coneVolume = deviceRange.getMaxConeVolume();
        System.out.println("油罐下锥体从体积：" + volume);
        volume += coneVolume;
        System.out.println("当前剩余总体积（包含下椎体体积）：" + volume);
        deviceRange.setStoreState(1);
        if(oilHeight <= deviceRange.getEmptyHeight()){//空仓
            deviceRange.setStoreState(0);

            //发送 空仓的 推送消息
            sendWxMsg(deviceRange);

        }else if(deviceRange.getCylinderHeight() - oilHeight <= deviceRange.getEmptyHeight()) {
            deviceRange.setStoreState(2);//满仓
        }

        //剩余总重量
        double totalWeight = volume * deviceRange.getPlotRatio();
        System.out.println("剩余重量：" + totalWeight + "吨");

        deviceRange.setTotalWeight(totalWeight); //1 立方米=1000 升
        return deviceRange;
    }

    public List<Double> getAllRecordPoints(List<DeviceRangeRecord> records,DeviceRangeRecord nowRecord, int lastLimit) {
        List<Double> powersNew = new ArrayList<>();
        List<Double> powers = new ArrayList<>();
        if(CollUtil.isNotEmpty(records)){
            for (DeviceRangeRecord portRecord : records){
                if(portRecord.getNowAngle() < nowRecord.getNowAngle()){
                    powers.add(portRecord.getNowHeight());
                }
            }
        }

        if(lastLimit == 0){
            powersNew.addAll(powers);
        }else{
            int startIndex = powers.size() - lastLimit;
            int index = 0;
            for (Double power : powers){
                if(index >= startIndex){
                    powersNew.add(power);
                }
                index ++;
            }
        }
        return powersNew;
    }

    /**
     *  获取 数据的斜率
     * @param powerList
     * @return
     */
    public static Map<String, Object> getPowerSlope(List<Double> powerList){
//        System.out.println("参与计算的数据个数：" + powerList.size());
//        Map<>
        double slope = 100d;
//		LinearRegression linearRegression1 = new LinearRegression();
        int i = 0;
        Map<Double, Double> initData = new HashMap<>();
        for (Double power : powerList){
            initData.put(Double.parseDouble((i+ 1) + ""), power);
            i++;
        }

//        System.out.println("斜率: " + slope);
//        System.out.println("截距: " + intercept);
        Map<String, Object> map = LinearRegression.initData(initData);
        int code = map.containsKey("code") ? Integer.parseInt(map.get("code").toString()) : 0;
        if(code == 1){
            slope = map.containsKey("slope") ? Double.parseDouble(map.get("slope").toString()) : 100d;
//            System.out.println("带符号的 斜率：" + slope);
            slope = Math.abs(MathUtil.getDoubleUpFour(slope));
//            System.out.println("绝对值 斜率：" + slope);
        }
        return map;
    }

    /**
     *  获取 最短斜边  可计算 上锥的 对应高度
     * @param deviceNum
     * @param dataCode
     * @return
     */
    @Override
    public DeviceRangeRecord getMinBevelByDeviceId(String deviceNum, String dataCode, double maxAngle, String tableName) {

        //判断当前是否需要重置 记录表
//        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
//        qw.orderByDesc("slope_last_ten");
//        qw.orderByDesc("now_bevel");
        qw.orderByAsc("now_height");
        qw.orderByDesc("now_angle");
        qw.gt("now_angle",maxAngle);
        qw.lt("now_angle",75);
        qw.last("limit 1");
        DeviceRangeRecord record = deviceRangeRecordDao.selectOne(qw);
        return record;
    }

    public DeviceRangeRecord getMinBevelByComputeRecords(List<DeviceRangeRecord> computeRecordsNew) {
        DeviceRangeRecord record = null;
        double bevel = 0;
        int index = 0;
        for (DeviceRangeRecord rangeRecord : computeRecordsNew){
            if(index == 0){
//                height = rangeRecord.getNowBevel();
                record = rangeRecord;
            }else{
                if(bevel < rangeRecord.getNowBevel()){
//                    height = rangeRecord.getNowBevel();
                    record = rangeRecord;
                }
            }
            index ++;
        }
        return record;
    }

    /**
     *  获取最后几组的数据的平均值
     * @param computeRecordsNew
     * @param lastCount
     * @return
     */
    public double getLastAvgHeight(List<DeviceRangeRecord> computeRecordsNew,int lastCount) {
        double height = 0;
        int index = 0;
        List<Double> listHeight = new ArrayList<>();
        int addIndex = computeRecordsNew.size() - lastCount;
        for (DeviceRangeRecord rangeRecord : computeRecordsNew){
            if(index >= addIndex){
//                System.out.println("rangeRecord.getNowHeight = " +rangeRecord.getNowHeight() );
                listHeight.add(rangeRecord.getNowHeight());
            }
            index ++;
        }

        for (Double heightLast : listHeight){
            height += heightLast;
        }
        height = height / lastCount;
        return height;
    }

    /**
     *  获取最小长边
     * @param computeRecords
     * @return
     */
    public DeviceRangeRecord getMinBevelByDeviceId(List<DeviceRangeRecord> computeRecords) {
        DeviceRangeRecord minRecord = null;
        int index = 0;
        for (DeviceRangeRecord rangeRecord : computeRecords){
            if(index == 0){
                minRecord = rangeRecord;
            }else{
                if(minRecord.getNowBevel() > rangeRecord.getNowBevel()){
                    minRecord = rangeRecord;
                }
            }
            index ++;
        }
        return minRecord;
    }


    /**
     *  获取最大长边
     * @param computeRecords
     * @return
     */
    public DeviceRangeRecord getMaxBevelByDeviceId(List<DeviceRangeRecord> computeRecords) {
        DeviceRangeRecord maxRecord = null;
        int index = 0;
        for (DeviceRangeRecord rangeRecord : computeRecords){
            if(index == 0){
                maxRecord = rangeRecord;
            }else{
                if(maxRecord.getNowBevel() < rangeRecord.getNowBevel()){
                    maxRecord = rangeRecord;
                }
            }
            index ++;
        }
        return maxRecord;
    }

    /**
     *  获取 最长斜边 的记录
     * @param deviceNum
     * @param dataCode
     * @return
     */
    @Override
    public DeviceRangeRecord getMaxBevelByDeviceId(String deviceNum, String dataCode) {

        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
//        qw.orderByDesc("slope_last_ten");
//        qw.orderByDesc("now_bevel");
        qw.orderByDesc("now_bevel");
        qw.orderByDesc("now_angle");
        qw.gt("now_angle",15);
        qw.last("limit 1");
        DeviceRangeRecord record = deviceRangeRecordDao.selectOne(qw);
        return record;
    }

    @Override
    public List<DeviceRangeRecord> getMaxHeightRecordByDeviceId(String deviceNum, String dataCode, double maxAngle, int limitCount) {

        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
        qw.ge("now_angle",maxAngle);
        qw.orderByDesc("now_height");
        qw.last("limit " + limitCount);

//        List<DeviceRangeRecord> records = deviceRangeRecordDao.selectList(qw);

        Map<String,Object> map = new HashMap<>();
        map.put("device_num",deviceNum);
        map.put("data_code",dataCode);
        map.put("now_angle",maxAngle);
        map.put("limit",limitCount);
        List<DeviceRangeRecord> records = deviceRangeRecordDao.getMaxHeightRecordByDeviceId(map);

        return records;
    }


    /**
     *  获取 最大高度的 记录
     * @param deviceNum
     * @param dataCode
     * @return
     */
    @Override
    public DeviceRangeRecord getMaxHeightByDeviceId(String deviceNum, String dataCode, String tableName) {

        //判断当前是否需要重置 记录表
//        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
        qw.orderByDesc("now_height");
        qw.last("limit 1");
        DeviceRangeRecord record = deviceRangeRecordDao.selectOne(qw);
        return record;
    }

    public DeviceRangeRecord getMaxHeightByComputeRecords(List<DeviceRangeRecord> computeRecordsNew) {
        DeviceRangeRecord record = null;
        double height = 0;
        int index = 0;
        for (DeviceRangeRecord rangeRecord : computeRecordsNew){
            if(index == 0){
                height = rangeRecord.getNowHeight();
                record = rangeRecord;
            }else{
                if(height < rangeRecord.getNowHeight()){
                    height = rangeRecord.getNowHeight();
                    record = rangeRecord;
                }
            }
            index ++;
        }
        return record;
    }

    public DeviceRangeRecord getMinHeightByComputeRecords(DeviceRange deviceRange, List<DeviceRangeRecord> computeRecordsNew) {
        DeviceRangeRecord record = null;
        double height = 0;
        int index = 0;
        double cylinderHeight = deviceRange.getCylinderHeight();

        for (DeviceRangeRecord rangeRecord : computeRecordsNew){
            if(rangeRecord.getNowBevel() > 0){
                if(index == 0){
                    height = cylinderHeight - rangeRecord.getNowHeight();
//                    System.out.println("第一高度：height 0 " + height);
                    record = rangeRecord;
                }else{
                    double nowHeight = cylinderHeight - rangeRecord.getNowHeight();
//                    System.out.println("第一高度：nowHeight" + nowHeight);
//                    System.out.println("第一高度：height" + height);
                    if(height < nowHeight){
                        height = nowHeight;
                        record = rangeRecord;
                    }
                }
                index ++;
            }
        }
        return record;
    }

    /**
     *  发送空仓推送消息
     * @param device
     */
    private void sendWxMsg(DeviceRange device){
        try{
            WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",9);
            if(wxTemplate!= null) {
                String accessToken = wxTemplateService.getAccessToken(wxTemplate.getAppId(), wxTemplate.getAppSecret(), 1);
                QueryWrapper<SysUser> qw = new QueryWrapper<>();
                qw.eq("shop_id", device.getShopId())
                        .and(wrapper -> wrapper.eq("user_type", 5).or().eq("user_type", 6));
                List<SysUser> sysUsers = sysUserService.list(qw);
                if (sysUsers != null && sysUsers.size() > 0) {
                    for (SysUser sysUser : sysUsers) {
                        List<User> users = userService.selectListByColumn("sys_user_id", sysUser.getUserId());
                        if (users != null) {
                            for (User user : users) {
                                if (user != null && sysUser.getIsSendMsg() == 1 && StrUtil.isNotEmpty(user.getUnionId())) {
                                    WxMsgTemplate template = getTemplate(wxTemplate, device, user, sysUser);
                                    String param = JSONUtil.parseObj(template).toString();
                                    JSONObject jsonObject = WxMessage.sendMsg(accessToken, param);
                                    System.out.println("微信公众号推送数据响应： " + jsonObject.toString());
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("发送失败" + e.getMessage());
        }
    }

    /**
     *  温度报警
     * @param device
     * @param user
     * @return
     */
    private WxMsgTemplate getTemplate(WxTemplate wxTemplate,DeviceRange device,User user, SysUser sysUser){
        WxMsgTemplate template = new WxMsgTemplate();
        UserMp userMp = userMpService.selectByUniqueColumn("unionid",user.getUnionId());
        if(userMp != null){
            template.setTouser(userMp.getOpenid());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");
            Map<String, MsgTempData> m = new HashMap<>();

            //报警项目
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            if(device.getDeviceType() == 0){
                first.setValue("管理员您好，仓库库存已不足预警");
            }
            m.put("first",first);

            //报警时间:2018年12月17日 13时20分05秒
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(DateUtil.getTime(new Date()));
            m.put("keyword1",keyword1);

            //地点:广州五山中公教育大厦1505房
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            Shop shop = shopService.findById(device.getShopId());
            if(shop != null){
                keyword2.setValue(shop.getShopName());
            }
            m.put("keyword2",keyword2);

            //设备:烟感设备
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue(device.getDeviceName() + "(设备编号："+device.getDeviceNum()+")");
            m.put("keyword3",keyword3);

            //报警内容:通道温度报警71.3℃
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getSpicalFontColor());
            keyword4.setValue("粮仓已空仓，请及时补仓！");
            m.put("keyword4",keyword4);

            //项目负责人:13500008624
            MsgTempData keyword5 = new MsgTempData();
            keyword5.setColor(wxTemplate.getSpicalFontColor());
            keyword5.setValue(sysUser.getName() + "("+sysUser.getMobile()+")");
            m.put("keyword5",keyword5);

            //贵司存在严重电气火灾安全隐患，为避免造成不可挽救后果，请及时处理！谢谢！
            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getSpicalFontColor());
            remark.setValue("粮仓已空仓，请及时补仓！请及时处理！");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }

    /**
     *  获取 最后一条 的记录
     * @param deviceNum
     * @param dataCode
     * @param isFirst  0 - 最后的测试值  1 - 最开始的测量值
     * @return
     */
    @Override
    public DeviceRangeRecord getLastRecordByDeviceId(String deviceNum, String dataCode,int isFirst, String tableName) {

        //判断当前是否需要重置 记录表
//        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> mapTable = new HashMap<>();
        mapTable.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(mapTable);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
        if(isFirst == 1){
            qw.orderByAsc("now_angle");
        }else{
            qw.orderByDesc("now_angle");
        }
        qw.gt("now_bevel",0);
        qw.last("limit 1");
        DeviceRangeRecord record = deviceRangeRecordDao.selectOne(qw);
        return record;
    }

    /**
     *  下椎体的 体积
     * @param deviceRange
     * @param dataCode
     * @return
     */
    private double getEmptyUpperConeVolume(DeviceRange deviceRange, String dataCode,double maxAngle){


        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();

        //上锥最短的斜边对应的记录
        DeviceRangeRecord record1 = getMinBevelByDeviceId(deviceRange.getDeviceNum(), dataCode,maxAngle, tableName);
        //最后的记录
        DeviceRangeRecord record2 = getLastRecordByDeviceId(deviceRange.getDeviceNum(), dataCode,0,tableName);

        double volume = 0d;

        System.out.println("最大深度：" + record1.getNowHeight());
        System.out.println("最后深度：" + record2.getNowHeight());
        // 取 高度绝对值
        double height = Math.abs(record1.getNowHeight() - record2.getNowHeight());

        Cone cone = new Cone();
        cone.setIsEllipse(0);
        cone.setRad(deviceRange.getStoreDiameter() / 2);
        cone.setHeight(height);

        volume = cone.volume();

        return volume;
    }

    /**
     *  粮食的下椎体 形状的时候  椎体的 体积
     * @param deviceRange
     * @return
     */
    private double getConeVolumeByRecord(DeviceRange deviceRange,double height){
        double volume = 0d;
//        System.out.println("最大深度：" + record1.getNowHeight());
//        System.out.println("最后深度：" + record2.getNowHeight());
        // 取 高度绝对值
//        double height = Math.abs(record1.getNowHeight() - record2.getNowHeight());

        Cone cone = new Cone();
        cone.setIsEllipse(0);
        cone.setRad(deviceRange.getStoreDiameter() / 2);
        cone.setHeight(height);
        volume = cone.volume();

        return volume;
    }

    private double getCylinderVolume(DeviceRange deviceRange, double height){
        double volume = 0d;
        Cylinder volu = new Cylinder();
        volu.setIsEllipse(deviceRange.getIsEllipse());
        if(deviceRange.getIsEllipse() == 1){
            volu.setLongHalf(deviceRange.getLongHalfShaft());
            volu.setShortHalf(deviceRange.getShortHalfShaft());
        }
        volu.setIsLie(deviceRange.getIsLie());
        //给半径和高赋值
        volu.setRad(deviceRange.getStoreDiameter() / 2);
        volu.setHeight(height);
        //输出
//        System.out.println("筒仓底面半径 = " + volu.getRad() + "米");
//        System.out.println("圆柱的高 = " + volu.getHeight()+ "米");
        //调用方法直接输出底面积
        volu.area();
        volume = volu.volume();
        return volume;
    }


    private double getRectVolume(DeviceRange deviceRange, double height){
        double volume = 0d;
        Rect rect = new Rect();
        rect.setLength(deviceRange.getRectLength());
        rect.setWidth(deviceRange.getRectWidth());
        rect.setHeight(height);
        volume = rect.volume();
        return volume;
    }


    /**
     *  下椎体的 体积
     * @param deviceRange
     * @param dataCode
     * @return
     */
    private double getEmptyLowerConeVolume(DeviceRange deviceRange, String dataCode,List<DeviceRangeRecord> computeRecordsNew, String tableName){
        //下锥最高的记录
//        DeviceRangeRecord record1 = getMaxHeightByComputeRecords(computeRecordsNew);
        DeviceRangeRecord record1 = getMaxHeightByDeviceId(deviceRange.getDeviceNum(), dataCode, tableName);

        //最后的记录
        DeviceRangeRecord record2 = getLastRecordByDeviceId(deviceRange.getDeviceNum(), dataCode,0, tableName);

        double volume = 0d;

        System.out.println("最大深度：" + record1.getNowHeight());
        System.out.println("最后深度：" + record2.getNowHeight());


        double maxHeight = record1.getNowHeight();
        if(record1.getVirtualAngle()!=null && record1.getVirtualAngle() > 0){
            maxHeight = MathUtil.getVerticalLength(record1.getVirtualAngle(), record1.getNowBevel());
            System.out.println("最大深度(重新计算)：" + maxHeight);
        }

        double height = maxHeight - record2.getNowHeight();
        System.out.println("下锥体的高：" + height);

        Cone cone = new Cone();
        cone.setIsEllipse(deviceRange.getIsEllipse());
        cone.setRad(deviceRange.getStoreDiameter() / 2);
        cone.setHeight(height);
        if(deviceRange.getIsEllipse() == 1){
            cone.setLongHalf(deviceRange.getLongHalfShaft());
            cone.setShortHalf(deviceRange.getShortHalfShaft());
        }else if(deviceRange.getIsEllipse() == 2){
            cone.setRectLength(deviceRange.getRectLength());
            cone.setRectWidth(deviceRange.getRectWidth());
        }
        volume = cone.volume();
        return volume;
    }


    @Override
    public long getRecordCount(String deviceNum, String dataCode) {

        //判断当前是否需要重置 记录表
        String tableName = addNowMonthRecordTable();
        // 配置表名
        Map<String,Object> map = new HashMap<>();
        map.put("ck_device_range_record", tableName);
        RequestDataHelper.setRequestData(map);

        QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
        qw.eq("device_num", deviceNum);
        qw.eq("data_code", dataCode);
        return deviceRangeRecordDao.selectCount(qw);
    }

    @Override
    public void testData(DeviceRangeRecord maxLength, DeviceRange deviceRange, String dataCode) {
        if(maxLength != null){
            //根据最长距离的点，来计算 空余 整体体积
            deviceRange = getLastEmptyVolume(maxLength,deviceRange,dataCode);
//            boolean bl = deviceRangeService.updateById(deviceRange);
//            if(!bl){
//                throw new TransactionalException("deviceRangeService updateById error");
//            }
        }
    }

    @Override
    public Map<String, Object> getChartDataByDeviceRangeByDataCode(User user, DeviceRange deviceRange, String dataCode) {

        Map<String,Object> mapReturn = new HashMap<>();


        deviceRange = deviceRangeService.getDeviceInfoByNum(deviceRange.getDeviceNum());

        QueryWrapper<DeviceRangeResult> qwResult = new QueryWrapper<>();
        qwResult.eq("device_id",deviceRange.getId());
        if(user.getIsTest() == 0){
            qwResult.eq("is_test", user.getIsTest()!= null ? user.getIsTest() : 0);
        }
        qwResult.eq("data_code", dataCode);
        qwResult.orderByDesc("create_time");
        qwResult.last("limit 1");
        DeviceRangeResult lastResult = deviceRangeResultDao.selectOne(qwResult);
        if(lastResult != null){

            //判断当前是否需要重置 记录表
            String tableName = lastResult.getRecordTableName();
            // 配置表名
            Map<String,Object> map = new HashMap<>();
            map.put("ck_device_range_record", tableName);
            RequestDataHelper.setRequestData(map);

            DeviceRangeRecord lastRecord = getLastRecordByDeviceId(lastResult.getDeviceNum(),dataCode,0, tableName);
            if(lastRecord!= null){
                double maxAngle = MathUtil.getAngleByBevel(lastRecord.getNowHeight(), deviceRange.getStoreDiameter());

                List<String> times = new ArrayList<>();
                List<String> values = new ArrayList<>();

                QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
                qw.eq("device_num",lastResult.getDeviceNum());
                qw.eq("data_code", lastResult.getDataCode());
                qw.gt("now_angle",maxAngle);
                qw.orderByAsc("now_angle");
                List<DeviceRangeRecord> rangeRecords = deviceRangeRecordDao.selectList(qw);
                for (DeviceRangeRecord rangeRecord : rangeRecords){
                    times.add(rangeRecord.getNowAngle() + "");
                    if(deviceRange.getDeviceType() == 0){
                        values.add((deviceRange.getCylinderHeight() - rangeRecord.getNowHeight())+"");
                    }else{
                        values.add(rangeRecord.getNowHeight()+"");
                    }
                }

                mapReturn.put("node_name", deviceRange.getDeviceNum());
                mapReturn.put("data_title", "垂直高度");
                mapReturn.put("data_unit", "M");
                mapReturn.put("data_code", lastResult.getDataCode());

                mapReturn.put("canvasImg","");
                mapReturn.put("times",times);
                mapReturn.put("values",values);
                mapReturn.put("count",times.size());
                mapReturn.put("maxValue",deviceRange.getStoreHeight());
                mapReturn.put("minValue",0);
            }
        }
        return mapReturn;
    }

    @Override
    public Map<String, Object> getChartDataByDeviceRange(User user,DeviceRange deviceRange) {
        Map<String,Object> mapReturn = new HashMap<>();

        deviceRange = deviceRangeService.getDeviceInfoByNum(deviceRange.getDeviceNum());

        QueryWrapper<DeviceRangeResult> qwResult = new QueryWrapper<>();
        qwResult.eq("device_id",deviceRange.getId());
        if(user.getIsTest() == 0){
            qwResult.eq("is_test", user.getIsTest()!= null ? user.getIsTest() : 0);
        }
        qwResult.orderByDesc("create_time");
        qwResult.last("limit 1");
        DeviceRangeResult lastResult = deviceRangeResultDao.selectOne(qwResult);
        if(lastResult != null){

            //判断当前是否需要重置 记录表
            String tableName = lastResult.getRecordTableName();
            // 配置表名
            Map<String,Object> map = new HashMap<>();
            map.put("ck_device_range_record", tableName);
            RequestDataHelper.setRequestData(map);

            DeviceRangeRecord lastRecord = getLastRecordByDeviceId(lastResult.getDeviceNum(),lastResult.getDataCode(),0,tableName);
            if(lastRecord!= null){

                double maxAngle = MathUtil.getAngleByBevel(lastRecord.getNowHeight(), deviceRange.getStoreDiameter());

                List<String> times = new ArrayList<>();
                List<String> values = new ArrayList<>();

                QueryWrapper<DeviceRangeRecord> qw = new QueryWrapper<>();
                qw.eq("device_num",lastResult.getDeviceNum());
                qw.eq("data_code", lastResult.getDataCode());
                qw.gt("now_angle",maxAngle);
                qw.orderByAsc("now_angle");
                List<DeviceRangeRecord> rangeRecords = deviceRangeRecordDao.selectList(qw);
                for (DeviceRangeRecord rangeRecord : rangeRecords){
                    times.add(rangeRecord.getNowAngle() + "");
                    if(deviceRange.getDeviceType() == 0){
                        values.add((deviceRange.getCylinderHeight() -  rangeRecord.getNowHeight())+"");
                    }else{
                        values.add(rangeRecord.getNowHeight()+"");
                    }
                }

                mapReturn.put("node_name", deviceRange.getDeviceNum());
                mapReturn.put("data_title", "垂直高度");
                mapReturn.put("data_unit", "M");
                mapReturn.put("data_code", lastResult.getDataCode());

                mapReturn.put("canvasImg","");
                mapReturn.put("times",times);
                mapReturn.put("values",values);
                mapReturn.put("count",times.size());
                mapReturn.put("maxValue",deviceRange.getStoreHeight());
                mapReturn.put("minValue",0);
            }
        }
        return mapReturn;
    }
}
